package com.senmiao.ssm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.senmiao.ssm.entity.*;
import com.senmiao.ssm.exception.MyException;
import com.senmiao.ssm.mapper.*;
import com.senmiao.ssm.pojo.vo.AdminInfoVo;
import com.senmiao.ssm.pojo.vo.OperateLogVo;
import com.senmiao.ssm.service.SecuritySecrecyService;
import com.senmiao.ssm.utils.Result;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class SecuritySecrecyServiceImpl implements SecuritySecrecyService {

    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private OperateLogMapper operateLogMapper;

    @Resource
    private OperateLogDetailMapper operateLogDetailMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private AdminMapper adminMapper;

    @Transactional
    @Override
    public Result authorizeAdminRole(Integer roleId, List<String> permissionIds) {
        // 检测角色id是否存在
        Role role = roleMapper.selectOne(new QueryWrapper<Role>().eq("id", roleId).eq("is_delete", 0));
        if (role == null){
            throw new MyException("角色id不存在");
        }
        // 删除该角色所有权限
        RolePermission clearRolePermission = new RolePermission();
        clearRolePermission.setIsDelete(1);
        rolePermissionMapper.update(clearRolePermission,new UpdateWrapper<RolePermission>().eq("role_id",roleId));

        if (permissionIds == null || permissionIds.size() <= 0){
            return Result.ok();
        }
        // 检测权限id是否存在
        checkPermissionExist(permissionIds);
        // 保存到角色-权限关系数据库
        for (String permissionId : permissionIds) {
            // 先从数据库中查询是否该关系记录
            RolePermission rolePermission = rolePermissionMapper.selectOne(
                    new QueryWrapper<RolePermission>().eq("role_id",roleId)
                            .eq("permission_id",permissionId));
            if (rolePermission == null){
                // 库中无该记录，保存
                rolePermission  = new RolePermission();
                rolePermission.setRoleId(roleId);
                rolePermission.setPermissionId(permissionId);
                rolePermission.setIsDelete(0);
                rolePermission.setAuthorityType(0);
                rolePermission.setCreateTime(new Date());
                int insert = rolePermissionMapper.insert(rolePermission);
                if (insert < 1){
                    throw new MyException("保存到数据库异常");
                }
            }else if (rolePermission.getIsDelete() == 1){
                rolePermission.setIsDelete(0);
                int update = rolePermissionMapper.updateById(rolePermission);
                if (update < 1){
                    throw new MyException("保存到数据库异常");
                }
            }
        }
        return Result.ok();
    }

    @Override
    public Result getAdminHavePermission(Integer adminId) {
        List<Permission> permissions = permissionMapper.listByAdminId(adminId);
        ArrayList<String> permissionIds = new ArrayList<>(permissions.size());
        for (Permission permission : permissions) {
            permissionIds.add(permission.getId());
        }
        return Result.ok().data("list",permissionIds).data("total",permissionIds.size());
    }

    @Override
    public Result listBusinessAndAuditOperatorLog(Integer pageNum, Integer limit) {
        ArrayList<Integer> roleIds = new ArrayList<>();
//        roleIds.add(1);// 系统管理员角色id
//        roleIds.add(2);// 安全保密员角色id
        roleIds.add(3);// 安全审计员角色id
        roleIds.add(4);// 业务管理员角色id
        Page<OperateLog> operateLogPage = operateLogMapper.listBusinessAndAuditOperateLog(new Page<>(pageNum,limit)
                ,getAllOperateTypeList()
                ,roleIds);
        ArrayList<OperateLogVo> operateLogVos = getOperateLogVos(operateLogPage);
        return Result.ok().data("list",operateLogVos)
                .data("total",operateLogPage.getTotal())
                .data("pageNum",operateLogPage.getCurrent());
    }

    @Override
    public Result listAdminLog(Integer pageNum, Integer limit) {
        // 获取所有角色id
        List<Role> allRole = roleMapper.selectList(new QueryWrapper<Role>().eq("is_delete", 0));
        ArrayList<Integer> allRoleIds = new ArrayList<>(allRole.size());
        for (Role role : allRole) {
            allRoleIds.add(role.getId());
        }
        // 通过角色去查询所有管理员日志信息
        Page<OperateLog> operateLogPage = operateLogMapper.listBusinessAndAuditOperateLog(new Page<>(pageNum,limit)
                ,getAllOperateTypeList(),allRoleIds);
        ArrayList<OperateLogVo> operateLogVos = getOperateLogVos(operateLogPage);
        return Result.ok().data("list",operateLogVos)
                .data("total",operateLogPage.getTotal())
                .data("pageNum",operateLogPage.getCurrent());
    }

    @Override
    public Result getRolePermission(Integer roleId) {
        return Result.ok().data("list"
                ,rolePermissionMapper.selectList(new QueryWrapper<RolePermission>()
                        .eq("role_id",roleId).eq("is_delete",0)));
    }

    /**
     * 检测权限id是否存在
     * @param permissionIds
     */
    private void checkPermissionExist(List<String> permissionIds){
        Integer count = permissionMapper.selectCount(new QueryWrapper<Permission>().in("id", permissionIds));
        if (count != permissionIds.size()){
            throw new MyException("权限id不存在");
        }
    }

    /**
     * 获得操作日志的详情
     * @param operateLogPage
     * @return
     */
    private ArrayList<OperateLogVo> getOperateLogVos(Page<OperateLog> operateLogPage) {
        ArrayList<OperateLogVo> operateLogVos = new ArrayList<>(operateLogPage.getRecords().size());
        for (OperateLog operateLog : operateLogPage.getRecords()) {
            OperateLogVo operateLogVo = new OperateLogVo();
            operateLogVo.setOperateLog(operateLog);
            if (operateLog.getType().equals(3)){
                // 该日志记录为更新操作，获取修改的字段详情
                List<OperateLogDetail> details = operateLogDetailMapper.selectList(
                        new QueryWrapper<OperateLogDetail>().eq("log_id", operateLog.getId()));
                operateLogVo.setDetails(details);
            }
            Integer adminId = operateLog.getAdminId();
            Admin admin = adminMapper.selectById(adminId);
            if (admin != null){
                AdminInfoVo adminInfoVo = new AdminInfoVo();
                BeanUtils.copyProperties(admin, adminInfoVo);
                operateLogVo.setAdminInfoVo(adminInfoVo);
            }
            operateLogVos.add(operateLogVo);
        }
        return operateLogVos;
    }

    /**
     * 获取所有操作日志类型，可以定义为一个常量
     * @return
     */
    private List<Integer> getAllOperateTypeList(){
        ArrayList<Integer> types = new ArrayList<>();
        types.add(0);// 日志类型：登录
        types.add(1);// 日志类型：登出
        types.add(2);// 日志类型：新增
        types.add(3);// 日志类型：更新
        types.add(4);// 日志类型：删除
        types.add(5);// 日志类型：查看
        return types;
    }
}